package com.atguigu.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

/**
 * @PACKAGE_NAME: com.atguigu.config
 * @CLASSNAME: WebSecurityConfig
 * @AUTHOR: zhangsan
 * @DATE: 2024/5/4 16:10
 * @SINCE 17.0.7
 * @DESCRIPTION: WebSecurityConfig
 * springSecurity 配置类,也可以用xml,此处我们使用配置类进行配置
 * 注解 @EnableWebSecurity 是开启SpringSecurity的默认行为
 */
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
//    @Override
//    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//        //super.configure(auth);
//        auth.inMemoryAuthentication().withUser("zhangsan")
//                .password(new BCryptPasswordEncoder().encode("123456"))
//                .roles("");//登录成功后的角色列表
//        auth.inMemoryAuthentication().withUser("lisi")
//                .password(new BCryptPasswordEncoder().encode("123456"))
//                .roles("ADMIN", "MEMBER");//不需要手写ROLE_
//    }

    /**
     * 必须指定加密方式,上下加密方式要一致
     *
     * @return
     */
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //必须调用父类的方法,否则就不需要认证即可访问
        //super.configure(http);
        //允许iframe嵌套显示
        http.headers().frameOptions().sameOrigin();
        //静态资源放行
        http.authorizeRequests()
                //允许匿名访问的路径
                .antMatchers("/static/**", "/loginPage").permitAll()
                //其他页面全部需要验证
                .anyRequest().authenticated();
        //登录设置
        http.formLogin()
                .loginPage("/loginPage") //登录表单页面地址
                .usernameParameter("username") //登录用户名
                .passwordParameter("password") //登录密码
                .loginProcessingUrl("/login") //提交表单的处理地址
                //.failureForwardUrl("/loginPage") //登录失败后,重定向到登录页面
                .defaultSuccessUrl("/"); //登录成功后,重定向的url
        //登出设置
        http.logout()
                .logoutUrl("/logout") //退出登录的路径,指定spring security拦截的登出url,退出功能是security提供的
                .logoutSuccessUrl("/loginPage") //用户退出后重定向的url
                .invalidateHttpSession(true); //禁用session
        //关闭csrf
        http.csrf().disable();

        //添加自定义无权限处理器
        http.exceptionHandling().accessDeniedHandler(new CustomAccessDeniedHandler());
    }
}
